{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# python修饰器\n",
    "## 函数作用域\n",
    "LEGB:L>E>G>B\n",
    "L:local 函数内部作用域\n",
    "E：enclosing 函数内部与内嵌函数之间\n",
    "G：global 全局作用域\n",
    "B：build-in 内置作用域"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "passline = 60\n",
    "\n",
    "def func(val):\n",
    "    passline = 90\n",
    "    if val >= passline:\n",
    "        print(\"pass\")\n",
    "    else:\n",
    "        print(\"failed\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "failed\n"
     ]
    }
   ],
   "source": [
    "func(89)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 闭包\n",
    "Closure:内部函数中对enclosing作用域的变量进行引用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 函数实质与属性\n",
    "### 1.函数是一个对象\n",
    "### 2.函数执行完成后内部变量回收\n",
    "### 3.函数属性\n",
    "### 4.函数返回值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "passline = 60\n",
    "\n",
    "def funb(val):\n",
    "    passline = 90\n",
    "    if val >= passline:\n",
    "        print(\"pass\")\n",
    "    else:\n",
    "        print(\"failed\")\n",
    "        \n",
    "    def in_func():\n",
    "        print(val)\n",
    "    in_func()  \n",
    "    return in_func()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "failed\n",
      "89\n",
      "89\n"
     ]
    }
   ],
   "source": [
    "f = funb(89)\n",
    "f"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_printer(msg1, msg2):\n",
    "    def printer():\n",
    "        print(msg1, msg2)\n",
    "    return printer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "printer = make_printer('Foo', 'Bar')  # 形成闭包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(<cell at 0x000001DB2D57F048: str object at 0x000001DB2D54BC38>,\n",
       " <cell at 0x000001DB2D57FD38: str object at 0x000001DB2D54B3E8>)"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "printer.__closure__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Foo'"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "printer.__closure__[0].cell_contents  # 第一个外部变量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Bar'"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "printer.__closure__[1].cell_contents  # 第二个外部变量"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
